
package com.xsj.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xsj.dto.ResponseDto;
import com.xsj.mapper.MerchantMapper;
import com.xsj.pojo.Merchant;
import com.xsj.pojo.MerchantType;
import com.xsj.service.MerchantService;

import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import com.xsj.xzxDto.ResponseDTO;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class MerchantServiceImpl implements MerchantService {
    @Autowired
    private MerchantMapper merchantMapper;

    private static final String DISTANCE_API_URL = "https://restapi.amap.com/v3/distance";

    private static final String KEY = "fb76db3ab9e55782539074c78c2f5ed7";


    public ResponseDto getMerchantInfo(Integer typeId, String selectedAddress, double latitude, double longitude) {
        // 分割获取地址信息
        String[] addressArray = selectedAddress.split("市");
        String city = addressArray[0];
        //根据地址和商家类型筛选商家信息
        List<Merchant> merchantInfo = merchantMapper.getMerchantInfo(typeId, city);
        //计算所有商家和用户的距离，并存储距离
        calculateBatchDistances(longitude, latitude, merchantInfo);
        // 按距离排序（过滤掉距离计算失败的商家并排序）
        merchantInfo.sort((o1, o2) -> {
            // 确保距离不为null，处理计算失败的情况
            Long dist1 = o1.getDistance() != null ? o1.getDistance() : Long.MAX_VALUE;
            Long dist2 = o2.getDistance() != null ? o2.getDistance() : Long.MAX_VALUE;
            return dist1.compareTo(dist2);
        });
        System.out.println("排序后的商家信息："+merchantInfo);
        //返回商家按照距离排序后的信息
        return ResponseDto.success(merchantInfo);
    }

    public Merchant getMerchantInfoById(Integer MerchantId) {
        return merchantMapper.getMerchantInfoById(MerchantId);
    }

    @Override
    public List<MerchantType> getMerchantType() {
        return merchantMapper.getMerchantType();
    }

    @Override
    public  List<HashMap<String,Object>> searchMerchant(String search) {
        return merchantMapper.searchMerchant(search);
    }

    @Override
    public ResponseDTO getMerInfoByLocation(double latitude, double longitude, String selectedAddress)  {
        // 分割获取地址信息
        String[] addressArray = selectedAddress.split("市");
        String city = addressArray[0];
        // 获取所有商家的信息
        List<Merchant> merchantLocation = merchantMapper.getMerchantLocation(city);

        // 计算每个商家与用户的距离
        calculateBatchDistances(longitude, latitude, merchantLocation);

        // 按距离排序（过滤掉距离计算失败的商家并排序）
        merchantLocation.sort((o1, o2) -> {
            // 确保距离不为null，处理计算失败的情况
            Long dist1 = o1.getDistance() != null ? o1.getDistance() : Long.MAX_VALUE;
            Long dist2 = o2.getDistance() != null ? o2.getDistance() : Long.MAX_VALUE;
            return dist1.compareTo(dist2);
        });
        System.out.println("排序后的商家信息："+merchantLocation);
        // 返回商家信息
        return ResponseDTO.Success(merchantLocation);
    }


    // 批量计算距离
    public static void calculateBatchDistances(double userLon, double userLat, List<Merchant> merchants)  {
        if (merchants == null || merchants.isEmpty()) {
            return;
        }
        System.out.println("获取的店家信息" + merchants);
        // 构造origins参数，格式为：经度1,纬度1|经度2,纬度2|...
        StringBuilder origins = new StringBuilder();
        Map<String, Merchant> merchantMap = new HashMap<>();
        for (int i = 0; i < merchants.size(); i++) {
            Merchant merchant = merchants.get(i);
            origins.append(merchant.getAddressLongitude())
                    .append(",")
                    .append(merchant.getAddressLatitude())
                    .append("|");
            merchantMap.put(String.valueOf(i + 1), merchant); // origin_id从1开始
        }
        if (origins.length() > 0) {
            origins.deleteCharAt(origins.length() - 1); // 移除最后一个"|"
        }

        // 使用URLEncoder.encode()对参数进行编码
        String encodedOrigins = URLEncoder.encode(origins.toString(), StandardCharsets.UTF_8);
        String url = DISTANCE_API_URL + "?key=" + KEY + "&origins=" + encodedOrigins
                + "&destination=" + userLon + "," + userLat + "&type=0";

        // 发送请求
        try (CloseableHttpClient httpClient = HttpClients.createDefault();
             CloseableHttpResponse response = httpClient.execute(new HttpGet(url))) {
            if (response.getStatusLine().getStatusCode() == 200) {
                String result = EntityUtils.toString(response.getEntity(), "UTF-8");
                JSONObject jsonObject = JSON.parseObject(result);

                if ("1".equals(jsonObject.getString("status"))) {
                    JSONArray results = jsonObject.getJSONArray("results");
                    for (int i = 0; i < results.size(); i++) {
                        JSONObject distanceInfo = results.getJSONObject(i);
                        String originId = distanceInfo.getString("origin_id");
                        Merchant merchant = merchantMap.get(originId);
                        if (merchant != null) {
                            Long distance = distanceInfo.getLong("distance");
                            merchant.setDistance(distance);
                        }
                    }
                } else {
                    throw new IOException("API error: " + jsonObject.getString("info"));
                }
            } else {
                throw new IOException("HTTP request failed with status: " + response.getStatusLine().getStatusCode());
            }
        } catch (ClientProtocolException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);

        }
    }
    /**
     * @Description: 用户传入用户位置，商家列表信息，返回距离信息
     * @Param: 用户经纬度
     * @Return: 商家信息列表按距离排序
     * @Author: 阿⭐
     * @Date: 2025/6/27
     */
//    public List<Merchant> merDistance(double latitude, double longitude,List<Merchant> merchantInfo) {
//
//        // 计算每个商家与用户的距离
//        for (Merchant merchant : merchantInfo) {
//            try {
//                long distance = getDistance(longitude,latitude,
//                        merchant.getAddressLongitude(),
//                        merchant.getAddressLatitude());
//                merchant.setDistance(distance);
//            } catch (IOException e) {
//                // 记录异常并设置默认距离（例如-1表示计算失败）
//                e.printStackTrace();
//                merchant.setDistance(-1L); // 或其他默认值
//            }
//        }
//
//        // 按距离排序（过滤掉距离计算失败的商家并排序）
//        merchantInfo.sort((o1, o2) -> {
//            // 确保距离不为null，处理计算失败的情况
//            Long dist1 = o1.getDistance() != null ? o1.getDistance() : Long.MAX_VALUE;
//            Long dist2 = o2.getDistance() != null ? o2.getDistance() : Long.MAX_VALUE;
//            return dist1.compareTo(dist2);
//        });
//        System.out.println("排序后的商家信息："+merchantInfo);
//        return merchantInfo;
//    }

    /**
     * @Description: 高德api距离计算
     * @Param: 目的地与出发地经纬度
     * @Return: 距离长度 单位为m
     * @Author: 阿⭐
     * @Date: 2025/6/27
     */
    public static long getDistance(double lon1, double lat1, double lon2, double lat2) throws IOException {
        // 构造请求URL
        String origins = lon1 + "," + lat1;
        String destination = lon2 + "," + lat2;
        String url = DISTANCE_API_URL + "?key=" + KEY + "&origins=" + origins + "&destination=" + destination + "&type=0";

        // 创建HttpClient
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet(url);

        // 发送请求
        try (CloseableHttpResponse response = httpClient.execute(httpGet)) {
            if (response.getStatusLine().getStatusCode() == 200) {
                String result = EntityUtils.toString(response.getEntity(), "UTF-8");
                JSONObject jsonObject = JSON.parseObject(result);

                // 解析响应
                if ("1".equals(jsonObject.getString("status"))) {
                    JSONArray results = jsonObject.getJSONArray("results");
                    if (!results.isEmpty()) {
                        JSONObject distanceInfo = results.getJSONObject(0);
                        // 添加休眠时间以降低QPS压力，例如每次调用后休眠200毫秒
                        TimeUnit.MILLISECONDS.sleep(300);
                        return distanceInfo.getLong("distance"); // 距离，单位：米
                    }
                } else {
                    throw new IOException("API error: " + jsonObject.getString("info"));
                }
            }
            throw new IOException("HTTP request failed with status: " + response.getStatusLine().getStatusCode());
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}